package quiz;

import java.util.ArrayList;
import java.util.HashSet;

public class Achievement {

	/* ================ STATIC METHODS AND VARIABLES ================ */

	public static final int AMATEUR_AUTHOR = 1;
	public static final int PROLIFIC_AUTHOR = 2;
	public static final int PRODIGIOUS_AUTHOR = 3;
	public static final int QUIZ_MACHINE = 4;
	public static final int I_AM_THE_GREATEST = 5;
	public static final int PRACTICE_MAKES_PERFECT = 6;
	public static final int SO_POPULAR = 7;
	public static final int COOLEST_KID_IN_SKOOL = 8;

	public static String getAchievementName(Achievement achievement) {
		switch(achievement.getAchievementID()) {
		case 1: return "Amateur Author: I've created a quiz! Teehee!";
		case 2: return "Prolific Author: I've created 5 quizzes! So hot right now!"; 
		case 3: return "Prodigious Author: I've created 10 quizzes! I need a life!";
		case 4: return "Quiz Mazhine: I've taken 10 quizzes! I find it pleasurable!";
		case 5: return "I am the Greatest: I've gotten the highest score on a quiz! Where did my friends go?"; 
		case 6: return "Practice Makes Perfect: I've taken a quiz in practice mode! I'm saving it for the big day!";
		case 7: return "So Popular: I have more than 10 friends! Jocks get at me!";
		case 8: return "Kewlest Kid In Skool: I have more than 20 friends! MC Hammer said it: Can't touch me!";
		default: return "I'm just an official Magic Quizzard!";
		}
	}


	private static ArrayList<Achievement> currentAchievements(Account account) {
		ArrayList<Achievement> achievements = new ArrayList<Achievement>();
		//amateur author, 1 quiz
		//prolific author, 5 quizzes
		//prodigious author, created 10 quizzes
		//quiz machine, took 10 quizzes
		//i am the greatest, highest score
		//practice makes perfect
		//so popular, more than 10 friends
		//coolest kid in school, more than 20 friends

		ArrayList<Quiz> quizzes = db.getQuizzesByUser(account);
		if(quizzes.size() >= 1) achievements.add(new Achievement(account.getID(), Achievement.AMATEUR_AUTHOR));
		if(quizzes.size() >= 5) achievements.add(new Achievement(account.getID(), Achievement.PROLIFIC_AUTHOR));
		if(quizzes.size() >= 10) achievements.add(new Achievement(account.getID(), Achievement.PRODIGIOUS_AUTHOR));

		ArrayList<Result> results = db.getRecentResultsForUser(account, Integer.MAX_VALUE); //get all quizzes taken by user
		if(results.size() >= 10) achievements.add(new Achievement(account.getID(), Achievement.QUIZ_MACHINE));

		ArrayList<Account> friends = db.getFriends(account.getID());
		if(friends.size() > 10) achievements.add(new Achievement(account.getID(), Achievement.SO_POPULAR));
		if(friends.size() > 20) achievements.add(new Achievement(account.getID(), Achievement.COOLEST_KID_IN_SKOOL));
		
		boolean hadTop = false;
		for(Result result : results) { //for every quiz taken
			ArrayList<Result> array = db.getTopQuizResults(result.getQuiz(), 1); //get the top result of the quiz
			if(array.get(0).equals(result) && !hadTop) { //if the user has the top result
				achievements.add(new Achievement(account.getID(), Achievement.I_AM_THE_GREATEST)); //add to list
				hadTop = true; //you're done
			}

		}

		if(db.userTookPractice(account.getID())) achievements.add(new Achievement(account.getID(), Achievement.PRACTICE_MAKES_PERFECT));


		return achievements;
	}

	public static ArrayList<Achievement> checkAchievements(Account account) {

		ArrayList<Achievement> current = currentAchievements(account);
		ArrayList<Achievement> past = db.getUserAchievements(account);

		HashSet<Achievement> filter = new HashSet<Achievement>();
		filter.addAll(current);
		filter.addAll(past);

		//find difference and store in database
		current.removeAll(past); //difference
		for(Achievement achievement : current) {
			db.storeAchievement(achievement);
		}

		if(current.size() > 0) return current;
		else return null;
	}

	/**
	 * Function sets the DataBase object that will be referenced by all answers
	 * MUST BE CALLED BEFORE ANY ANSWERS ARE CREATED
	 * @param db - the DataBase object referenced by all accounts 
	 */
	public static void setDataBase(DataBase database){
		db = database;
		db.open();
	}
	public static DataBase db;


	/* ================ STATIC METHODS AND VARIABLES ================ */

	/* ================ PRIVATE INSTANCE VARIABLES ================ */


	private int achievementID;
	private Account account;
	private int id;

	/* ================ PRIVATE INSTANCE VARIABLES ================ */


	public Achievement(int userID, int achievementID) {
		this.account = db.getAccount(userID);
		this.achievementID = achievementID;
	}

	public Achievement(Account account, int achievementID) {
		this.account = account;
		this.achievementID = achievementID;
	}

	/* ================ GETTERS ================ */

	public int getID() {
		return id;
	}

	public int getAchievementID() {
		return achievementID;
	}

	public int getUserID() {
		return account.getID();
	}

	public Account getAccount() {
		return account;
	}



	/* ================ GETTERS ================ */


	/* ================ SETTERS ================ */




	public void setID(int num) {
		id = num;
	}

	public void setAchievementID(int achievementID) {
		this.achievementID = achievementID;
	}

	public void setAccount(int userID) {
		this.account = db.getAccount(userID);
	}

	public void setAccount(Account account) {
		this.account = account;
	}



	/* ================ SETTERS ================ */



	@Override
	public int hashCode() {
		final int prime = 31;
		int result = 1;
		result = prime * result + achievementID;
		result = prime * result + id;
		result = prime * result + account.getID();
		return result;
	}

	@Override
	public boolean equals(Object obj) {
		if (this == obj)
			return true;
		if (obj == null)
			return false;
		if (getClass() != obj.getClass())
			return false;
		Achievement other = (Achievement) obj;
		if (achievementID != other.achievementID)
			return false;
		if (!account.equals(other.account))
			return false;
		return true;
	}



}
